package com.ruiyian.bridge.project.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.ruiyian.bridge.info.domain.DipmonitorInfo;
import com.ruiyian.bridge.info.domain.DistanceInfo;
import com.ruiyian.bridge.info.domain.Mmh2oInfo;
import com.ruiyian.bridge.info.service.*;
import com.ruiyian.bridge.project.domain.BridgeInfo;
import com.ruiyian.bridge.project.domain.DeviceType;
import com.ruiyian.bridge.project.domain.DeviceWarnSet;
import com.ruiyian.bridge.project.domain.MeasurePoint;
import com.ruiyian.bridge.project.domain.vo.DataAnalysisDto;
import com.ruiyian.bridge.project.domain.vo.DataAnalysisVo;
import com.ruiyian.bridge.project.domain.vo.Mmh2oQueryBo;
import com.ruiyian.bridge.project.enums.DeviceTypeEnum;
import com.ruiyian.bridge.project.enums.WarnDgreeEnum;
import com.ruiyian.bridge.project.mapper.MeasurePointMapper;
import com.ruiyian.bridge.project.service.BridgeInfoService;
import com.ruiyian.bridge.project.service.DeviceTypeService;
import com.ruiyian.bridge.project.service.DeviceWarnSetService;
import com.ruiyian.bridge.project.service.MeasurePointfoService;
import com.ruiyian.common.utils.DateUtils;
import com.ruiyian.common.utils.NumberFormatUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 测点信息Service业务层处理
 *
 * @author ruiyian
 * @date 2022-01-20
 */
@Service
public class MeasurePointServiceImpl extends ServiceImpl<MeasurePointMapper,MeasurePoint> implements MeasurePointfoService
{
    @Autowired
    private MeasurePointMapper measurePointMapper;
    @Autowired
    private DeviceWarnSetService deviceWarnSetService;
    @Autowired
    private DeviceTypeService deviceTypeService;
    @Autowired
    private DistanceInfoService distanceInfoService;
    @Autowired
    private TemperatureService temperatureService;
    @Autowired
    private VehicleWeightService vehicleWeightService;
    @Autowired
    private VibrationAccelerationService vibrationAccelerationService;
    @Autowired
    private Mmh2oInfoService mmh2oInfoService;
    @Autowired
    private DipmonitorInfoService dipmonitorInfoService;
    @Autowired
    private BridgeInfoService bridgeInfoService;
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    /**
     *
     * @param measurePoint
     * @return measurePoint
     */
    @Override
    public List<MeasurePoint> selectTSensorTypeList(MeasurePoint measurePoint) {
        return  measurePointMapper.getSensorNoByCondition(measurePoint);
    }

    /**
     * 查询测点信息
     *
     * @param id 测点信息主键
     * @return 测点信息
     */
    @Override
    public MeasurePoint selectTSensorInfoById(Long id)
    {
        return measurePointMapper.selectTSensorInfoById(id);
    }

    /**
     * 查询测点信息列表
     *
     * @param measurePoint 测点信息
     * @return 测点信息
     */
    @Override
    public List<MeasurePoint> selectTSensorInfoList(MeasurePoint measurePoint)
    {
        return measurePointMapper.selectTSensorInfoList(measurePoint);
    }

    /**
     * 新增测点信息
     *
     * @param measurePoint 测点信息
     * @return 结果
     */
    @Override
    public int insertTSensorInfo(MeasurePoint measurePoint)
    {
        measurePoint.setCreateTime(DateUtils.getNowDate());
        return measurePointMapper.insertTSensorInfo(measurePoint);
    }

    /**
     * 修改测点信息
     *
     * @param measurePoint 测点信息
     * @return 结果
     */
    @Override
    public int updateTSensorInfo(MeasurePoint measurePoint)
    {
        measurePoint.setUpdateTime(DateUtils.getNowDate());
        return measurePointMapper.updateTSensorInfo(measurePoint);
    }

    /**
     * 批量删除测点信息
     *
     * @param ids 需要删除的测点信息主键
     * @return 结果
     */
    @Override
    public int deleteTSensorInfoByIds(Long[] ids)
    {
        return measurePointMapper.deleteTSensorInfoByIds(ids);
    }

    /**
     * 删除测点信息信息
     *
     * @param id 测点信息主键
     * @return 结果
     */
    @Override
    public int deleteTSensorInfoById(Long id)
    {
        return measurePointMapper.deleteTSensorInfoById(id);
    }


    /**
     * 根据桥梁获取测点信息
     * @param bridgeId
     * @return
     */
    @Override
    public List<Map<String, Object>> getMeasPointList(Long bridgeId) {
        BridgeInfo bridgeInfo = bridgeInfoService.selectTBridgeInfoById(bridgeId);
        List<MeasurePoint> measPointList = measurePointMapper.getMeasPointList(bridgeId);
        Map<String, List<MeasurePoint>> collect = measPointList.stream().filter(f -> StringUtils.isNotBlank(f.getType())).collect(Collectors.groupingBy(p -> p.getType()));
        List<Map<String, Object>> list = Lists.newArrayList();
        //获取预警设置列表
        List<DeviceWarnSet> setList = deviceWarnSetService.selectTSensorWarnSetList(new DeviceWarnSet());
        Double yellow1 = 0.0;
        Double orange1 = 0.0;
        Double red1 = 0.0;
        Double yellowW = 0.0;
        Double orangeW = 0.0;
        Double redW = 0.0;
        Double yellowV = 0.0;
        Double orangeV = 0.0;
        Double redV = 0.0;
        for (DeviceWarnSet DeviceWarnSet : setList) {
            if (WarnDgreeEnum.YELLOW.getWarnDgree().equals(DeviceWarnSet.getWarnDgree())) {
                yellow1 = DeviceWarnSet.getDisLimitUpVlue();
                yellowW = DeviceWarnSet.getLimitWeight();
            }
            if (WarnDgreeEnum.ORANGE.getWarnDgree().equals(DeviceWarnSet.getWarnDgree())) {
                orange1 = DeviceWarnSet.getDisLimitUpVlue();
                orangeW = DeviceWarnSet.getLimitWeight();
            }
            if (WarnDgreeEnum.RED.getWarnDgree().equals(DeviceWarnSet.getWarnDgree())) {
                red1 = DeviceWarnSet.getDisLimitUpVlue();
                redW = DeviceWarnSet.getLimitWeight();
            }
        }
        for (Map.Entry<String, List<MeasurePoint>> map : collect.entrySet()) {
            Map<String, Object> data = Maps.newHashMap();
            DeviceType byType = deviceTypeService.getByType(map.getKey());
            if (null != byType) {
                data.put("icon", byType.getIcon());
                data.put("name", byType.getName());
            }
            data.put("type", map.getKey());
            data.put("num", map.getValue().size());
            // 激光
            List<MeasurePoint> value = map.getValue();
            if (value.size() > 0) {
                for (MeasurePoint se : value) {
                    if (map.getKey().equals(DeviceTypeEnum.DISTANCE.getType().toString())) {
                        DataAnalysisVo distanceInfo = distanceInfoService.getNowMinData(se.getAddr(), se.getMacaddr());
                        if (null != distanceInfo) {
                            Double distance = Double.parseDouble(distanceInfo.getDistance()) - se.getBaseVlue();
                            BigDecimal bigDecimal = new BigDecimal(distance).setScale(2, BigDecimal.ROUND_DOWN);
                            se.setDistance(bigDecimal.toString());
                            se.setDistanceTime(distanceInfo.getDatetime());
                            String status = checkData(se.getDistance(), yellow1, orange1, red1);
                            se.setStatus(status);
                            se.setDistance(se.getDistance()+"mm");
                            se.setYellowStatus(yellow1+"mm");
                            se.setStatusName(getStatusName(status));
                        } else {
                            se.setStatus("-1");
                            se.setStatusName("离线");
                            se.setYellowStatus(yellow1+"mm");
                        }
                    } else if (map.getKey().equals(DeviceTypeEnum.TEMPERATURE.getType().toString())) {
                        // 温度传感器
                        DataAnalysisVo nowMinData = temperatureService.getNowMinData(se.getAddr(), se.getMacaddr());
                        if(null!=nowMinData){
                            Double distance =  Double.parseDouble(nowMinData.getTemperature());
                            se.setDistance(NumberFormatUtil.twoDecimals(distance)+"℃");
                            se.setDistanceTime(DateUtils.dateTime("yyyy-MM-dd HH:mm:ss",nowMinData.getCreatTime()));
                            se.setStatus("0");
                            se.setStatusName("正常");
                        }else{
                            se.setStatus("-1");
                            se.setStatusName("离线");
//                            se.setYellowStatus(String.valueOf(yellow1));
                        }
                    }else if (map.getKey().equals(DeviceTypeEnum.WEIGHT.getType().toString())) {
                        // 车重
                        DataAnalysisVo nowMinData = vehicleWeightService.getNowMinData(se.getAddr(), se.getMacaddr());
                        if(null!=nowMinData){
                            Double distance =  Double.parseDouble(nowMinData.getWeight());
                            se.setDistance(NumberFormatUtil.twoDecimals(distance));
                            se.setDistanceTime(nowMinData.getDatetime());
                            String status = checkData(se.getDistance(), yellowW, orangeW, redW);
                            se.setStatus(status);
                            se.setDistance(se.getDistance()+"kg");
                            se.setYellowStatus(yellowW+"kg");
                            se.setStatusName(getStatusName(status));
                        }else{
                            se.setStatus("-1");
                            se.setStatusName("离线");
                            se.setYellowStatus(String.valueOf(yellowW));
                        }
                    }else if (map.getKey().equals(DeviceTypeEnum.VIBRATIONACCELERATION.getType().toString())) {
                        // 振动加速度
                        DataAnalysisVo nowMinData = vibrationAccelerationService.getNowMinData(se.getAddr(), se.getMacaddr());
                        if(null!=nowMinData){
                            Double distance =  Double.parseDouble(nowMinData.getAcceleration());
                            se.setDistance(NumberFormatUtil.twoDecimals(distance));
                            se.setDistanceTime(nowMinData.getDatetime());
                            String status = checkData(se.getDistance(), yellowV, orangeV, redV);
                            se.setStatus(status);
                            se.setDistance(se.getDistance()+"m/s");
                            se.setYellowStatus(yellowV+"m/s");
                            se.setStatusName(getStatusName(status));
                        }else{
                            se.setStatus("-1");
                            se.setStatusName("离线");
                            se.setYellowStatus(String.valueOf(yellowV));
                        }
                    }else if (map.getKey().equals(DeviceTypeEnum.MMH2O.getType().toString())) {
                        // 静力
                        DataAnalysisVo nowMinData = mmh2oInfoService.getNowMinData(se.getAddr(), se.getMacaddr());
                        if(null!=nowMinData){
                            Double distance =  Double.parseDouble(nowMinData.getJgValue().replaceAll("[-+^:,]","").trim())-se.getBaseVlue();
                            BigDecimal bigDecimal = new BigDecimal(distance).setScale(2, BigDecimal.ROUND_DOWN);
                            se.setDistance(bigDecimal.toString());
                            se.setDistanceTime(nowMinData.getDatetime());
                            String status = checkData(se.getDistance(), yellow1, orange1, red1);
                            se.setStatus(status);
                            se.setDistance(se.getDistance()+"mm");
                            se.setYellowStatus(yellow1+"mm");
                            se.setStatusName(getStatusName(status));
                        }else{
                            se.setStatus("-1");
                            se.setStatusName("离线");
                            se.setYellowStatus(yellow1+"mm");
                        }
                    }else if (map.getKey().equals(DeviceTypeEnum.DIPMONITOR.getType().toString())) {
                        // 倾角
                        DataAnalysisVo nowMinData = dipmonitorInfoService.getNowMinData(se.getAddr(), se.getMacaddr());
                        if(null!=nowMinData){
                            String xVal = nowMinData.getXval().replaceAll("[-+^:,]", "").trim();
                            String yVal = nowMinData.getYval().replaceAll("[-+^:,]", "").trim();
                            String zVal = nowMinData.getZval().replaceAll("[-+^:,]", "").trim();
                            se.setDistance("x："+xVal+"，y："+yVal+"，z："+zVal);
                            se.setDistanceTime(nowMinData.getDatetime());
                            String status = checkData(xVal, yellow1, orange1, red1);
                            se.setStatus(status);
                            se.setDistance(se.getDistance()+"mm");
                            se.setYellowStatus(yellow1+"mm");
                            se.setStatusName(getStatusName(status));
                        }else{
                            se.setStatus("-1");
                            se.setStatusName("离线");
                            se.setYellowStatus(yellow1+"mm");
                        }
                    }
                }
            }
            data.put("equipmentList", value);
            data.put("bridgeInfo",bridgeInfo);
            data.put("bridgeName",bridgeInfo.getBridgeName());
            data.put("bridgeId",bridgeId);
            list.add(data);
        }
        return list;
    }
    /**
     * 获取当前状态值
     *
     * @param record
     * @param yellow
     * @param orange
     * @param red
     * @return
     */
    private String checkData(String record, Double yellow, Double orange, Double red) {
        String rest;
        try {
            double data = Double.valueOf(record);
            //data  = Math.abs(data);
            if (data < yellow) {
                rest = "0";
            } else if (data < orange) {
                rest = "1";
            } else if (data < red) {
                rest = "2";
            } else {
                rest = "3";
            }
        } catch (Exception e) {
            rest = "-1";
        }
        return rest;
    }

    private String getStatusName(String status) {
        String rest = "离线";
        switch (status) {
            case "-1":
                rest = "离线";
                break;
            case "0":
                rest = "正常";
                break;
            case "1":
                rest = "黄色预警";
                break;
            case "2":
                rest = "橙色预警";
                break;
            case "3":
                rest = "红色预警";
                break;
            default:
                break;
        }
        return rest;
    }
    /**
     * 获取测点数据 统计数据
     * @param bo
     * @return
     */
    @Override
    public Map<String, Object> queryDataListByAddr(Mmh2oQueryBo bo) {
        Map<String, Object> map = null;
        if(bo.getType().equals(DeviceTypeEnum.DISTANCE.getType().toString())){
           map = distanceInfoService.queryDataListByAddr(bo);
        }else if(bo.getType().equals(DeviceTypeEnum.MMH2O.getType().toString())){
            map =  mmh2oInfoService.queryDataListForSummary(bo);
        }else if(bo.getType().equals(DeviceTypeEnum.DIPMONITOR.getType().toString())){
            map =  dipmonitorInfoService.queryDataListByAddr(bo);
        }
        return map;
    }

    /**
     * 数据查看 多维度统计
     * @param dto
     * @return
     */
    @Override
    public Map<String, Object> lookData(DataAnalysisDto dto) {
        Map<String,Object> returnData = Maps.newHashMap();
        List<String> xAxis = Lists.newArrayList();
        List<Map<String,Object>> series = Lists.newArrayList();
        List<DataAnalysisVo> distanceInfos = null;
        if(dto.getShebeiType1()== DeviceTypeEnum.DISTANCE.getType()){
            // 激光
            distanceInfos = distanceInfoService.queryDisByDateType(dto);
        }else if(dto.getShebeiType1()== DeviceTypeEnum.VIBRATIONACCELERATION.getType()){
            // 加速度
            distanceInfos =  vibrationAccelerationService.queryByDateType(dto);
        }else if(dto.getShebeiType1()== DeviceTypeEnum.TEMPERATURE.getType()){
            // 温度
            distanceInfos =  temperatureService.querySameTempByDateType(dto);
        }else if(dto.getShebeiType1()== DeviceTypeEnum.WEIGHT.getType()){
            // 车重
            distanceInfos =  vehicleWeightService.queryByDateType(dto);

        }else if(dto.getShebeiType1()== DeviceTypeEnum.MMH2O.getType()){
            // 静力
            distanceInfos =  mmh2oInfoService.queryDisByDateType(dto);
        }else if(dto.getShebeiType1()== DeviceTypeEnum.DIPMONITOR.getType()){
            // 倾角
            distanceInfos =  dipmonitorInfoService.queryByDateType(dto);
        }
        List<String> value = Lists.newArrayList();
        if(distanceInfos.size()>0){
            distanceInfos.stream().peek(d->{
                xAxis.add(d.getCreatTime());
                try {
                    // 反射根据key获取对应监测项值
                    Field field = d.getClass().getDeclaredField(dto.getItem1());
                    field.setAccessible(true);
                    String s = (String) field.get(d);
                    value.add(s);
                } catch (Exception e) {
//                    log.error("获取数据失败");
                }
            }).collect(Collectors.toList());
            Map<String,Object> map = Maps.newHashMap();
            map.put("data",value);
            map.put("type","line");
            map.put("showSymbol",false);
            series.add(map);
        }
        returnData.put("category",xAxis);
        returnData.put("series",series);
        return returnData;
    }

    /**
     * 测点数据同步
     */
    @Override
    public void dataSyncAll() {
        try {
            Long aLong = distanceInfoService.queryCount();
            // 远程
            Long rLong = distanceInfoService.queryRemoteCount();
            if(aLong<rLong){
                List<DataAnalysisVo> dataList = distanceInfoService.getDataList(aLong, rLong - aLong);
                List<DistanceInfo> list = new ArrayList<>();
                dataList.stream().peek(p->{
                    DistanceInfo distanceInfo = new DistanceInfo();
                    distanceInfo.setCreattime(p.getDatetime());
                    distanceInfo.setDistance(p.getDistance());
                    distanceInfo.setAddr(p.getAddr());
                    distanceInfo.setMacaddr(p.getMacAddr());
                    distanceInfo.setId(p.getId());
                    list.add(distanceInfo);
                }).collect(Collectors.toList());
                distanceInfoService.saveBatch(list);
                logger.info("激光 数据同步成功----");
            }
        } catch (Exception e) {
            logger.error("激光数据同步异常"+e.getMessage());
        }

        // 静力
        try {
            Long mLong = mmh2oInfoService.queryCount();
            // 远程
            Long rmLong = mmh2oInfoService.queryRemoteCount();
            if(mLong<rmLong){
                List<DataAnalysisVo> dataList = mmh2oInfoService.getDataList(mLong, rmLong - mLong);
                List<Mmh2oInfo> list = new ArrayList<>();
                dataList.stream().peek(f->{
                    Mmh2oInfo mmh2oInfo = new Mmh2oInfo();
                    mmh2oInfo.setAddr(f.getAddr());
                    mmh2oInfo.setCreattime(f.getDatetime());
                    mmh2oInfo.setMacaddr(f.getMacAddr());
                    mmh2oInfo.setJgvalue(f.getJgValue());
                    mmh2oInfo.setTemp(f.getTemp());
                    mmh2oInfo.setMmh2o(f.getMmh2o());
                    mmh2oInfo.setId(f.getId());
                    list.add(mmh2oInfo);
                }).collect(Collectors.toList());
                mmh2oInfoService.saveBatch(list);
                logger.info("静力 数据同步成功----");
            }
        } catch (Exception e) {
            logger.error("静力同步异常"+e.getMessage());
        }

        // 倾角
        try {
            Long dLong = dipmonitorInfoService.queryCount();
            // 远程
            Long rdLong = dipmonitorInfoService.queryRemoteCount();
            if(dLong<rdLong){
                List<DataAnalysisVo> dataList = dipmonitorInfoService.getDataList(dLong, rdLong - dLong);
                List<DipmonitorInfo> list = new ArrayList<>();
                dataList.stream().peek(f->{
                    DipmonitorInfo dipmonitorInfo = new DipmonitorInfo();
                    dipmonitorInfo.setAddr(f.getAddr());
                    dipmonitorInfo.setChecktime(f.getDatetime());
                    dipmonitorInfo.setMacaddr(f.getMacAddr());
                    dipmonitorInfo.setXval(f.getXval());
                    dipmonitorInfo.setYval(f.getYval());
                    dipmonitorInfo.setZval(f.getZval());
                    dipmonitorInfo.setId(f.getId());
                    list.add(dipmonitorInfo);
                }).collect(Collectors.toList());
                dipmonitorInfoService.saveBatch(list);
                logger.info("倾角 数据同步成功----");
            }
        } catch (Exception e) {
            logger.error("倾角同步异常"+e.getMessage());
        }
    }

    @Override
    public List<MeasurePoint> getMeasPointListAll() {
        return measurePointMapper.getMeasPointListAll();
    }
}
